home *** CD-ROM | disk | FTP | other *** search
/ Scena PL EXE / scenapl-1995-exe.iso / torba szopy / muzyka / aplayer / developers / examples / apsoundmon20library.s < prev   
Text File  |  1995-10-19  |  24KB  |  1,094 lines

  1. ; $VER: SoundMon20.library 2.0
  2. ;
  3.  
  4.     INCDIR    "Includes3.0:Include3.0/"
  5.     INCLUDE    "Exec/Types.i"
  6.     INCLUDE    "Own/SystemBases.i"
  7.     INCLUDE    "Own/SystemStructures.i"
  8.     INCLUDE    "Own/SystemOffsets.i"
  9.     INCLUDE    "Own/AccessiblePlayer.i"
  10.  
  11.  
  12. VERSION        =    2
  13. REVISION    =    0
  14.  
  15. TRUE        =    -1
  16. FALSE        =    0
  17.  
  18. ; Library Data
  19.  
  20. LN_Name        =    10
  21. LN_Type        =    8
  22. NT_Library    =    9
  23.  
  24. LIBB_Summing    =    0
  25. LIBB_Changed    =    1
  26. LIBB_SumUsed    =    2
  27. LIBB_DelExp    =    3
  28.  
  29. LIBF_Summing    =    1<<LIBB_Summing
  30. LIBF_Changed    =    1<<LIBB_Changed
  31. LIBF_SumUsed    =    1<<LIBB_SumUsed
  32. LIBF_DelExp    =    1<<LIBB_DelExp
  33.  
  34. ; Macros
  35.  
  36. INBYTE    MACRO
  37.     dc.b    %11100000,0
  38.     dc.w    \1
  39.     dc.b    \2,0
  40.     ENDM
  41.  
  42. INWORD    MACRO
  43.     dc.b    %11010000,0
  44.     dc.w    \1,\2
  45.     ENDM
  46.  
  47. INLONG    MACRO
  48.     dc.b    %11000000,0
  49.     dc.w    \1
  50.     dc.l    \2
  51.     ENDM
  52.  
  53. ; Library Base Structure
  54.  
  55.     STRUCTURE LibraryStruct,0
  56.     STRUCT    LIB_Node,14
  57.     UBYTE    LIB_Flags
  58.     UBYTE    LIB_Pad
  59.     UWORD    LIB_NegSize
  60.     UWORD    LIB_PosSize
  61.     UWORD    LIB_Version
  62.     UWORD    LIB_Revision
  63.     APTR    LIB_IDString
  64.     ULONG    LIB_Sum
  65.     UWORD    LIB_OpenCnt
  66.  
  67.     LONG    LIB_SegList
  68.     LABEL    LibraryStruct_SIZEOF
  69.  
  70.  
  71.     SECTION    SoundMon20.library,CODE
  72.  
  73. START    moveq    #0,d0
  74.     rts
  75. ;------------------------------------------------------------------------------
  76. LIBNAME    dc.b    "apSoundMon20.library",0
  77.  
  78. LIBID    dc.b    "SoundMon20.library 2.0 (17-June-1994)",0
  79.     even
  80. ;------------------------------------------------------------------------------
  81. ; ROMTAG Structure
  82. ;
  83.  
  84. ROMTAG    dc.w    $4afc            ;ROMTAG Indentifier
  85.     dc.l    romtag
  86.     dc.l    slut
  87.     dc.b    $80            ;Flags
  88.     dc.b    version
  89.     dc.b    $09            ;Type Of Module
  90.     dc.b    $00            ;Initialization Priority
  91.     dc.l    libname
  92.     dc.l    libid
  93.     dc.l    autinit            ;Pointer To AUTOINIT Table
  94. ;------------------------------------------------------------------------------
  95. ; AUTOINIT Table
  96. ;
  97.  
  98. AUTINIT    dc.l    LibraryStruct_SIZEOF    ;Size Of Structure AFTER Base Address
  99.     dc.l    vector            ;Pointer To Vector Table
  100.     dc.l    inittab            ;Pointer To Init Structure
  101.     dc.l    init            ;Pointer To Init Routine
  102. ;------------------------------------------------------------------------------
  103. ; Init Table
  104. ;
  105.  
  106. INITTAB    INBYTE    LN_Type,NT_Library
  107.     INBYTE    LIB_Flags,LIBF_SumUsed!LIBF_Changed
  108.     INWORD    LIB_Version,version
  109.     INWORD    LIB_Revision,revision
  110.     INLONG    LN_Name,libname
  111.     INLONG    LIB_IDString,libid
  112.     dc.l    0
  113. ;------------------------------------------------------------------------------
  114. ; Vector Table
  115. ;
  116.  
  117. VECTOR    dc.w    -1
  118.     dc.w    opnlib-vector,clslib-vector,expunge-vector,extfunc-vector
  119.     dc.w    SM_GetTags-vector
  120.     dc.w    -1
  121. ;------------------------------------------------------------------------------
  122. ; Init Routine
  123. ;
  124.  
  125. INIT    movem.l    d1-d7/a0-a6,-(sp)
  126.     move.l    d0,a4            ;Base Address
  127.     move.l    a0,LIB_SegList(a4)
  128.  
  129.     move.l    a4,d0
  130.     movem.l    (sp)+,d1-d7/a0-a6
  131.     rts
  132. ;------------------------------------------------------------------------------
  133. ; Offset  -6: Open Library
  134. ;
  135.  
  136. OPNLIB    addq.w    #1,LIB_OpenCnt(a6)
  137.     bclr    #LIBB_DelExp,LIB_Flags(a6)
  138.     move.l    a6,d0
  139.     rts
  140. ;------------------------------------------------------------------------------
  141. ; Offset -12: Close Library
  142. ;
  143.  
  144. CLSLIB    moveq    #0,d0
  145.     subq.w    #1,LIB_OpenCnt(a6)
  146.     bne.b    clslibo
  147.     btst    #LIBB_DelExp,LIB_Flags(a6)
  148.     bne.b    expunge
  149. CLSLIBO    rts
  150. ;------------------------------------------------------------------------------
  151. ; Offset -18: Expunge
  152. ;
  153.  
  154. EXPUNGE    movem.l    d1-d7/a0-a6,-(sp)
  155.     move.l    a6,a4
  156.     tst.w    LIB_OpenCnt(a4)
  157.     beq.b    exp1
  158.     bset    #LIBB_DelExp,LIB_Flags(a4)
  159.     moveq    #0,d0
  160.     bra.b    expungo
  161.  
  162. EXP1    move.l    4.w,a6
  163.     move.l    LIB_SegList(a4),d2
  164.     move.l    a4,a1
  165.     jsr    Remove(a6)
  166.  
  167.     move.l    a4,a1
  168.     moveq    #0,d0
  169.     move.w    LIB_NegSize(a4),d0
  170.     sub.l    d0,a1
  171.     add.w    LIB_PosSize(a4),d0
  172.     jsr    FreeMem(a6)
  173.     move.l    d2,d0
  174.  
  175. EXPUNGO    movem.l    (sp)+,d1-d7/a0-a6
  176.     rts
  177. ;------------------------------------------------------------------------------
  178. ; Offset -24: ExtFunc
  179. ;
  180.  
  181. EXTFUNC    moveq    #0,d0
  182.     rts
  183. ;------------------------------------------------------------------------------
  184. ;******************************************************************************
  185. ;* Sound Monitor 2.0 Player
  186. ;******************************************************************************
  187. ;------------------------------------------------------------------------------
  188. ; Structure
  189. ;
  190.  
  191.     STRUCTURE SoundMonStruct,0
  192.     APTR    SMON_Global
  193.     APTR    SMON_Module
  194.     APTR    SMON_Tables
  195.     UWORD    SMON_DMA
  196.     UWORD    SMON_BPStep
  197.     UBYTE    SMON_NumTables
  198.     UBYTE    SMON_ArpCount
  199.     UBYTE    SMON_BPCount
  200.     UBYTE    SMON_BPDelay
  201.     UBYTE    SMON_ST
  202.     UBYTE    SMON_TR
  203.     UBYTE    SMON_BPPatCount
  204.     UBYTE    SMON_BPRepCount
  205.     STRUCT    SMON_Samples,15*4
  206.     STRUCT    SMON_BPCurrent,14+18+32*3
  207.     STRUCT    SMON_BPBuffer,144
  208.     LABEL    SoundMonStruct_SIZEOF
  209. ;------------------------------------------------------------------------------
  210. ; Offset -30: GetTags
  211. ;
  212. ; IN :    Nothing
  213. ;
  214. ; OUT:    A0 = Pointer To A TagList
  215. ;
  216.  
  217. SM_GetTags
  218.     lea    SM_Tags(pc),a0
  219.     rts
  220.  
  221. SM_Tags    dc.l    APT_EarlyCheck,SM_TestModule
  222.  
  223.     dc.l    APT_InitSound,SM_InitSound
  224.     dc.l    APT_EndSound,SM_EndSound
  225.     dc.l    APT_Interrupt,SM_PlayModule
  226.  
  227.     dc.l    APT_PlayerName,smname
  228.     dc.l    APT_Description,smdes
  229.     dc.l    APT_ModuleName,SM_ModuleName
  230.  
  231.     dc.l    APT_Volume,TRUE
  232.     dc.l    APT_Pause,TRUE
  233.  
  234.     dc.l    APT_GetMaxPattern,SM_GetMaxPattern
  235.     dc.l    APT_GetMaxSample,SM_GetMaxSample
  236.     dc.l    APT_GetSongLength,SM_GetSongLength
  237.  
  238.     dc.l    APT_GetSongPos,SM_GetSongPos
  239.     dc.l    APT_Rewind,SM_Rewind
  240.     dc.l    APT_Forward,SM_Forward
  241.     dc.l    TAG_END
  242.  
  243. SMNAME    dc.b    "Sound Monitor 2.0",0
  244. SMDES    dc.b    "Original player by Brian Postma.",10
  245.     dc.b    "Adapted by Tax.",0
  246.     even
  247. ;------------------------------------------------------------------------------
  248. ; TestModule
  249. ;
  250. ; IN :    Nothing
  251. ;
  252. ; OUT:    D0 = Success (0=Unknown, 1=Ok, 2=Error)
  253. ;
  254.  
  255. SM_TestModule
  256.     movem.l    d1-d2/a0/a4-a5,-(sp)
  257.  
  258.     subq.l    #4,sp
  259.     moveq    #$1a,d1
  260.     moveq    #4,d2
  261.     move.l    sp,a0
  262.     move.l    APG_CheckLoad(a5),a4
  263.     jsr    (a4)            ;Read Mark
  264.     move.l    (sp)+,d1
  265.     tst.l    d0
  266.     beq.b    .tsmod1
  267.  
  268.     moveq    #0,d0            ;Unknown
  269.     lsr.l    #8,d1
  270.     cmp.l    #"V.2",d1
  271.     bne.b    .tsmodo
  272.     moveq    #1,d0            ;Ok
  273.     bra.b    .tsmodo
  274.  
  275. .TSMOD1    moveq    #2,d0            ;Error
  276. .TSMODO    movem.l    (sp)+,d1-d2/a0/a4-a5
  277.     rts
  278. ;------------------------------------------------------------------------------
  279. ; InitSound
  280. ;
  281. ; IN :    A1 = Address
  282. ;
  283. ; OUT:    Nothing
  284. ;
  285.  
  286. SM_InitSound    movem.l    d0-d2/a0-a1/a4,-(sp)
  287.         lea    SM_DataArea,a4
  288.         move.l    a1,SMON_Module(a4)
  289.         move.l    a5,SMON_Global(a4)
  290.  
  291.         move.b    #1,SMON_ArpCount(a4)
  292.         move.b    #1,SMON_BPCount(a4)
  293.         move.b    #6,SMON_BPDelay(a4)
  294.         move.b    #1,SMON_BPRepCount(a4)
  295.  
  296.         clr.w    SMON_DMA(a4)
  297.         clr.w    SMON_BPStep(a4)
  298.         clr.b    SMON_BPPatCount(a4)
  299.         clr.b    SMON_ST(a4)
  300.         clr.b    SMON_TR(a4)
  301.  
  302.         lea    SMON_BPCurrent(a4),a0
  303.         lea    null,a1
  304.         clr.l    (a0)+
  305.         move.l    a1,(a0)+
  306.         move.w    #1,(a0)+
  307.         clr.l    (a0)+
  308.  
  309.         clr.l    (a0)+
  310.         clr.l    (a0)+
  311.         clr.l    (a0)+
  312.         clr.w    (a0)+
  313.         clr.w    (a0)+
  314.         clr.w    (a0)+
  315.  
  316.         moveq    #3-1,d0
  317. .initloop    clr.l    (a0)+
  318.         move.l    a1,(a0)+
  319.         move.w    #1,(a0)+
  320.         clr.l    (a0)+
  321.         clr.l    (a0)+
  322.         clr.l    (a0)+
  323.         clr.l    (a0)+
  324.         clr.l    (a0)+
  325.         clr.w    (a0)+
  326.         dbra    d0,.initloop
  327.  
  328.         lea    SMON_BPBuffer(a4),a0
  329.         moveq    #(144/2)-1,d0
  330. .initloop1    clr.w    (a0)+
  331.         dbra    d0,.initloop1
  332.  
  333.         lea    SMON_Samples(a4),a0
  334.         move.l    SMON_Module(a4),a1
  335.  
  336.         clr.b    SMON_NumTables(a4)
  337.         cmp.w    #'V.',26(a1)
  338.         bne.b    bpnotv2
  339.         cmp.b    #'2',28(a1)
  340.         bne.b    bpnotv2
  341.         move.b    29(a1),SMON_NumTables(a4)
  342.  
  343. bpnotv2        move.l    #512,d0
  344.         move.w    30(a1),d1    ;d1 now contains length in steps
  345.         moveq    #1,d2        ;1 is highest pattern number
  346.         mulu    #4,d1        ;4 voices per step
  347.         subq.w    #1,d1        ;correction for DBRA
  348. findhighest    cmp.w    (a1,d0),d2    ;Is it higher
  349.         bge.b    nothigher    ;No
  350.         move.w    (a1,d0),d2    ;Yes, so let D2 be highest
  351. nothigher    addq.l    #4,d0        ;Next Voice
  352.         dbra    d1,findhighest    ;And search
  353.  
  354.         move.w    30(a1),d1
  355.         lsl.w    #4,d1        ;16 bytes per step
  356.         move.l    #512,d0        ;header is 512 bytes
  357.         mulu    #48,d2        ;48 bytes per pattern
  358.         add.l    d2,d0
  359.         add.l    d1,d0        ;offset for samples
  360.         add.l    SMON_Module(a4),d0
  361.         move.l    d0,SMON_Tables(a4)
  362.         moveq    #0,d1
  363.         move.b    SMON_NumTables(a4),d1    ;Number of tables
  364.         lsl.l    #6,d1            ;x 64
  365.         add.l    d1,d0
  366.  
  367.         moveq    #15-1,d1    ;15 samples
  368.         lea    32(a1),a1
  369. initloop    move.l    d0,(a0)+
  370.         cmp.b    #$ff,(a1)
  371.         beq.b    bpissynth
  372.         move.w    24(a1),d2
  373.         add.w    d2,d2
  374.         add.l    d2,d0        ;offset next sample
  375. bpissynth    lea    32(a1),a1    ;Length of Sample Part in header
  376.         dbra    d1,initloop
  377.  
  378.         movem.l    (sp)+,d0-d2/a0-a1/a4
  379.         rts
  380. ;------------------------------------------------------------------------------
  381. ; EndSound
  382. ;
  383. ; IN :    A1 = Address
  384. ;
  385. ; OUT:    Nothing
  386. ;
  387.  
  388. SM_EndSound
  389.     move.l    d0,-(sp)
  390.     moveq    #0,d0
  391.     move.w    d0,$dff0a8
  392.     move.w    d0,$dff0b8
  393.     move.w    d0,$dff0c8
  394.     move.w    d0,$dff0d8
  395.     move.w    #$000f,$dff096
  396.     move.l    (sp)+,d0
  397.     rts
  398. ;------------------------------------------------------------------------------
  399. ; PlayModule
  400. ;
  401. ; IN :    A1 = Address
  402. ;    D1 = VBlank/Cia (0=CIA)
  403. ;
  404. ; OUT:    Nothing
  405. ;
  406.  
  407. SM_PlayModule    movem.l    d0-d7/a0-a6,-(sp)
  408.         lea    SM_DataArea,a5
  409.         bsr.b    bpmusic
  410.         movem.l    (sp)+,d0-d7/a0-a6
  411.         rts
  412.  
  413. bpmusic        bsr.w    bpsynth
  414.         subq.b    #1,SMON_ArpCount(a5)
  415.         moveq    #3,d0
  416.         lea    SMON_BPCurrent(a5),a0
  417.         lea    $dff0a0,a1
  418. bploop1        move.b    12(a0),d4
  419.         ext.w    d4
  420.         add.w    d4,(a0)
  421.         tst.b    $1e(a0)
  422.         bne.b    bplfo
  423.         move.w    (a0),6(a1)
  424. bplfo        move.l    4(a0),(a1)
  425.         move.w    8(a0),4(a1)
  426.         tst.b    11(a0)
  427.         bne.b    bpdoarp
  428.         tst.b    13(a0)
  429.         beq.b    not2
  430. bpdoarp        tst.b    SMON_ArpCount(a5)
  431.         bne.b    not0
  432.         move.b    11(a0),d3
  433.         move.b    13(a0),d4
  434.         and.w    #240,d4
  435.         and.w    #240,d3
  436.         lsr.w    #4,d3
  437.         lsr.w    #4,d4
  438.         add.w    d3,d4
  439.         add.b    10(a0),d4
  440.         bsr.w    bpplayarp
  441.         bra.b    not2
  442.  
  443. not0        cmpi.b    #1,SMON_ArpCount(a5)
  444.         bne.b    not1
  445.         move.b    11(a0),d3
  446.         move.b    13(a0),d4
  447.         and.w    #15,d3
  448.         and.w    #15,d4
  449.         add.w    d3,d4
  450.         add.b    10(a0),d4
  451.         bsr.w    bpplayarp
  452.         bra.b    not2
  453.  
  454. not1        move.b    10(a0),d4
  455.         bsr.w    bpplayarp
  456. not2        lea    $10(a1),a1
  457.         lea    $20(a0),a0
  458.         dbra    d0,bploop1
  459.  
  460.         tst.b    SMON_ArpCount(a5)
  461.         bne.b    arpnotzero
  462.         move.b    #3,SMON_ArpCount(a5)
  463. arpnotzero    subq.b    #1,SMON_BPCount(a5)
  464.         beq.b    bpskip1
  465.         rts
  466.  
  467. bpskip1        move.b    SMON_BPDelay(a5),SMON_BPCount(a5)
  468. bpplay        bsr.b    bpnext
  469.         move.w    SMON_DMA(a5),$dff096
  470.  
  471.         move.l    SMON_Global(a5),a1
  472.         move.l    APG_WaitDma(a1),a1
  473.         jsr    (a1)            ;Wait For DMA
  474.  
  475.         moveq    #3,d0
  476.         lea    $dff0a0,a1
  477.         moveq    #1,d1
  478.         move.l    a5,-(sp)
  479.         lea    SMON_BPCurrent(a5),a2
  480.         lea    SMON_BPBuffer(a5),a5
  481. bploop2        btst    #15,(a2)
  482.         beq.b    bpskip7
  483.         bsr.w    bpplayit
  484. bpskip7        asl.w    #1,d1
  485.         lea    $10(a1),a1
  486.         lea    $20(a2),a2
  487.         lea    $24(a5),a5
  488.         dbra    d0,bploop2
  489.         move.l    (sp)+,a5
  490.         rts
  491.  
  492. bpnext        clr.w    SMON_DMA(a5)
  493.         move.l    SMON_Module(a5),a0
  494.         lea    $dff0a0,a3
  495.         moveq    #3,d0
  496.         moveq    #1,d7
  497.         lea    SMON_BPCurrent(a5),a1
  498. bploop3        moveq    #0,d1
  499.         move.w    SMON_BPStep(a5),d1
  500.         lsl.w    #4,d1
  501.         move.l    d0,d2
  502.         lsl.l    #2,d2
  503.         add.l    d2,d1
  504.         add.l    #512,d1
  505.         move.w    (a0,d1),d2
  506.         move.b    2(a0,d1),SMON_ST(a5)
  507.         move.b    3(a0,d1),SMON_TR(a5)
  508.         subq.w    #1,d2
  509.         mulu    #48,d2
  510.         moveq    #0,d3
  511.         move.w    30(a0),d3
  512.         lsl.w    #4,d3
  513.         add.l    d2,d3
  514.         move.l    #$00000200,d4
  515.         move.b    SMON_BPPatCount(a5),d4
  516.         add.l    d3,d4
  517.         move.l    d4,a2
  518.         add.l    a0,a2
  519.         moveq    #0,d3 
  520.         move.b    (a2),d3
  521.         tst.b    d3
  522.         bne.b    bpskip4
  523.         bra.w    bpoptionals
  524.  
  525. bpskip4        clr.w    12(a1)            ;Clear autoslide/autoarpeggio
  526.         move.b    1(a2),d4
  527.         and.b    #15,d4
  528.         cmpi.b    #10,d4            ;Option 10->transposes off
  529.         bne.b    bp_do1
  530.         move.b    2(a2),d4
  531.         and.b    #240,d4              ;Higher nibble=transpose
  532.         bne.b    bp_not1
  533. bp_do1        add.b    SMON_TR(a5),d3
  534.         ext.w    d3
  535. bp_not1        move.b    d3,10(a1)         ;Voor Arpeggio's
  536.         lea    bpper(pc),a4
  537.         lsl.w    #1,d3
  538.         move.w    -2(a4,d3.w),(a1)
  539.         bset    #15,(a1)
  540.         move.b    #$ff,2(a1)
  541.         moveq    #0,d3
  542.         move.b    1(a2),d3
  543.         lsr.b    #4,d3
  544.         and.b    #15,d3
  545.         tst.b    d3
  546.         bne.b    bpskip5
  547.         move.b    3(a1),d3 
  548. bpskip5     move.b    1(a2),d4
  549.         and.b    #15,d4
  550.         cmpi.b    #10,d4             ;option 10
  551.         bne.b    bp_do2
  552.         move.b    2(a2),d4
  553.         and.b    #15,d4
  554.         bne.b    bp_not2
  555. bp_do2        add.b    SMON_ST(a5),d3
  556. bp_not2        cmpi.w    #1,8(a1)
  557.         beq.b    bpsamplechange
  558.         cmp.b    3(a1),d3
  559.         beq.b    bpoptionals
  560. bpsamplechange    move.b    d3,3(a1)
  561.         or.w    d7,SMON_DMA(a5)
  562. bpoptionals     moveq    #0,d3
  563.         moveq    #0,d4
  564.         move.b    1(a2),d3
  565.         and.b    #15,d3
  566.         move.b    2(a2),d4
  567.  
  568.         cmpi.b    #0,d3            ; Optionals Here
  569.         bne.b    notopt0
  570.         move.b    d4,11(a1)
  571.  
  572. notopt0        cmpi.b    #1,d3
  573.         bne.b    bpskip3
  574.         move.l    d0,-(sp)
  575.         move.b    d4,2(a1)         ; Volume ook in BPCurrent
  576.         move.b    d4,d0
  577.         bsr.w    calvol
  578.         move.w    d0,8(a3)
  579.         move.l    (sp)+,d0
  580.  
  581. bpskip3        cmpi.b    #2,d3              ; Set Speed
  582.         bne.b    bpskip9
  583.         move.b    d4,SMON_BPCount(a5)
  584.         move.b    d4,SMON_BPDelay(a5)
  585.  
  586. bpskip9        cmpi.b    #3,d3             ; Filter = LED control
  587.         bne.b    bpskipa
  588.         tst.b    d4
  589.         bne.b    bpskipb
  590.         bset    #1,$bfe001
  591.         bra.b    bpskip2
  592. bpskipb        bclr    #1,$bfe001
  593.  
  594. bpskipa        cmpi.b    #4,d3             ; PortUp
  595.         bne.b    noportup
  596.         sub.w    d4,(a1)            ; Slide data in BPCurrent
  597.         clr.b    11(a1)             ; Arpeggio's uit
  598.  
  599. noportup    cmpi.b    #5,d3             ; PortDown
  600.         bne.b    noportdn
  601.         add.w    d4,(a1)            ; Slide down
  602.         clr.b    11(a1)
  603.  
  604. noportdn    cmpi.b    #6,d3            ; SetRepCount
  605.         bne.b    notopt6
  606.         move.b    d4,SMON_BPRepCount(a5)
  607.  
  608. notopt6        cmpi.b    #7,d3            ; DBRA repcount
  609.         bne.b    notopt7
  610.         subq.b    #1,SMON_BPRepCount(a5)
  611.         beq.b    notopt7
  612.         move.w    d4,SMON_BPStep(a5)
  613.  
  614. notopt7        cmpi.b    #8,d3            ;Set AutoSlide
  615.         bne.b    notopt8
  616.         move.b    d4,12(a1)
  617.  
  618. notopt8        cmpi.b    #9,d3            ;Set AutoArpeggio
  619.         bne.b    notopt9
  620.         move.b    d4,13(a1)
  621.  
  622. notopt9
  623. bpskip2        lea    $10(a3),a3
  624.         lea    $20(a1),a1
  625.         asl.w    #1,d7
  626.         dbra    d0,bploop3
  627.  
  628.         addq.b    #3,SMON_BPPatCount(a5)
  629.         cmpi.b    #48,SMON_BPPatCount(a5)
  630.         bne.b    bpskip8
  631.         move.b    #0,SMON_BPPatCount(a5)
  632.         addq.w    #1,SMON_BPStep(a5)
  633.  
  634.         move.l    SMON_Global(a5),a2
  635.         move.l    APG_SendMsg(a2),a2
  636.         move.w    #MSG_NextPos,d2
  637.         jsr    (a2)
  638.  
  639.         move.l    SMON_Module(a5),a0
  640.         move.w    30(a0),d1
  641.         cmp.w    SMON_BPStep(a5),d1
  642.         bne.b    bpskip8
  643.         move.w    #0,SMON_BPStep(a5)
  644.  
  645.         move.l    SMON_Global(a5),a2
  646.         move.l    APG_SendMsg(a2),a2
  647.         move.w    #MSG_NextMod,d2
  648.         jsr    (a2)
  649. bpskip8        rts
  650.  
  651. bpplayit    bclr    #15,(a2)
  652.         tst.l    (a5)             ;Was EG used
  653.         beq.b    noeg1             ;No ??
  654.         moveq    #0,d3             ;Well then copy
  655.         move.l    (a5),a4            ;Old waveform back
  656.         moveq    #7,d7             ;to waveform tables
  657. eg1loop        move.l    4(a5,d3.w),(a4)+    ;Copy...
  658.         addq.w    #4,d3             ;Copy...
  659.         dbra    d7,eg1loop        ;Copy...
  660.  
  661. noeg1        move.w    (a2),6(a1)        ;Period from bpcurrent
  662.         moveq    #0,d7
  663.         move.b    3(a2),d7        ;Instrument number
  664.         move.l    d7,d6             ;Also in d6
  665.         lsl.l    #5,d7             ;Header offset
  666.         move.l    4(sp),a3
  667.         move.l    SMON_Module(a3),a3
  668.         cmpi.b    #$ff,(a3,d7.w)        ;Is synthetic
  669.         beq.w    bpplaysynthetic        ;Yes ??
  670.         clr.l    (a5)             ;EG Off
  671.         clr.b    $1a(a2)            ;Synthetic mode off
  672.         clr.w    $1e(a2)            ;Lfo Off
  673.         add.l    #24,d7             ;24 is name->ignore
  674.         lsl.l    #2,d6             ;x4 for sample offset
  675.         move.l    4(sp),a4
  676.         lea    SMON_Samples(a4),a4
  677.         move.l    -4(a4,d6),d4        ;Fetch sample pointer
  678.         beq.b    bp_nosamp        ;is zero->no sample
  679.         move.l    d4,(a1)         ;Sample pointer in hardware
  680.         move.w    (a3,d7),4(a1)        ;length in hardware
  681.  
  682.         movem.l    d0/a5,-(sp)
  683.         move.l    12(sp),a5
  684.         move.b    2(a2),d0
  685.         bsr.w    calvol
  686.         movem.l    (sp)+,d0/a5
  687.  
  688.         cmpi.b    #$ff,2(a2)        ;Use default volume
  689.         bne.b    skipxx             ;No ??
  690.  
  691.         movem.l    d0/a5,-(sp)
  692.         move.l    12(sp),a5
  693.         move.w    6(a3,d7),d0
  694.         bsr.w    calvol
  695.         move.w    d0,8(a1)
  696.         movem.l    (sp)+,d0/a5
  697.  
  698. skipxx         move.w    4(a3,d7),8(a2)        ;Length in bpcurrent
  699.         moveq    #0,d6
  700.         move.w    2(a3,d7),d6        ;Calculate repeat
  701.         add.l    d6,d4
  702.         move.l    d4,4(a2)        ;sample start in bpcurrent
  703.         cmpi.w    #1,8(a2)        ;has sample repeat part
  704.         bne.b    bpskip6            ;Yes ??
  705. bp_nosamp    move.l    #null,4(a2)        ;Play no sample
  706.         bra.b    bpskip10
  707.  
  708. bpskip6        move.w    8(a2),4(a1)        ;Length to hardware
  709.         move.l    4(a2),(a1)        ;pointer to hardware
  710. bpskip10    or.w    #$8000,d1        ;Turn on DMA for this voice
  711.         move.w    d1,$dff096        ;Yeah, do it
  712.         rts
  713.  
  714. bpplaysynthetic    move.b    #$1,$1a(a2)        ;Synthetic mode on
  715.         clr.w    $e(a2)             ;EG Pointer restart
  716.         clr.w    $10(a2)         ;LFO Pointer restart
  717.         clr.w    $12(a2)         ;ADSR Pointer restart
  718.         move.w    22(a3,d7.w),$14(a2)    ;EG Delay
  719.         addq.w    #1,$14(a2)        ;0 is nodelay
  720.         move.w    14(a3,d7.w),$16(a2)    ;LFO Delay
  721.         addq.w    #1,$16(a2)        ;So I need correction
  722.         move.w    #1,$18(a2)        ;ADSR Delay->Start immediate
  723.         move.b    17(a3,d7.w),$1d(a2)    ;EG OOC
  724.         move.b    9(a3,d7.w),$1e(a2)    ;LFO OOC
  725.         move.b    4(a3,d7.w),$1f(a2)    ;ADSR OOC
  726.         move.b    19(a3,d7.w),$1c(a2)    ;Current EG Value
  727.         move.l    4(sp),a4
  728.         move.l    SMON_Tables(a4),a4    ; so far so good,now what ??
  729.         moveq    #0,d3            ;Pointer to waveform tables
  730.         move.b    1(a3,d7.w),d3        ;Which waveform
  731.         lsl.l    #6,d3             ;x64 is length waveform table
  732.         add.l    d3,a4
  733.         move.l    a4,(a1)         ;Sample Pointer
  734.         move.l    a4,4(a2)        ;In bpcurrent
  735.         move.w    2(a3,d7.w),4(a1)    ;Length in words
  736.         move.w    2(a3,d7.w),8(a2)    ;Length in bpcurrent
  737.         tst.b    4(a3,d7.w)        ;Is ADSR on
  738.         beq.b    bpadsroff        ;No ??
  739.         move.l    4(sp),a4
  740.         move.l    SMON_Tables(a4),a4    ;Tables
  741.         moveq    #0,d3
  742.         move.b    5(a3,d7.w),d3        ;ADSR table number
  743.         lsl.l    #6,d3             ;x64 for length
  744.         add.l    d3,a4             ;Add it
  745.         moveq    #0,d3
  746.         move.b    (a4),d3         ;Get table value
  747.         add.b    #128,d3         ;I want it from 0..255
  748.         lsr.w    #2,d3             ;Divide by 4->0..63
  749.         cmpi.b    #$ff,2(a2)
  750.         bne.b    bpskip99
  751.         move.b    25(a3,d7.w),2(a2)
  752. bpskip99    moveq    #0,d4
  753.         move.b    2(a2),d4        ;Default volume
  754.         mulu    d4,d3             ;default maal init volume
  755.         lsr.w    #6,d3             ;divide by 64
  756.  
  757.         movem.l    d0/a5,-(sp)
  758.         move.l    12(sp),a5
  759.         move.w    d3,d0
  760.         bsr.w    calvol
  761.         move.w    d0,8(a1)        ;is new volume
  762.         movem.l    (sp)+,d0/a5
  763.         bra.b    bpflipper
  764.  
  765. bpadsroff    movem.l    d0/a5,-(sp)
  766.         move.l    12(sp),a5
  767.         move.b    2(a2),d0
  768.         bsr.w    calvol
  769.         move.w    d0,8(a1)        ;is new volume
  770.         movem.l    (sp)+,d0/a5
  771.  
  772.         cmpi.b    #$ff,2(a2)
  773.         bne.b    bpflipper        ;No ADSR
  774.         movem.l    d0/a5,-(sp)
  775.         move.l    12(sp),a5
  776.         move.b    25(a3,d7.w),d0
  777.         bsr.w    calvol
  778.         move.w    d0,8(a1)        ;So use default volume
  779.         movem.l    (sp)+,d0/a5
  780.  
  781. bpflipper    move.l    4(a2),a4        ;Pointer on waveform
  782.         move.l    a4,(a5)            ;Save it
  783.         moveq    #0,d3             ;Save Old waveform
  784.         moveq    #7,d4             ;data in bpbuffer
  785. eg2loop        move.l    (a4,d3.w),4(a5,d3.w)
  786.         addq.w    #4,d3             ;Copy         
  787.         dbra    d4,eg2loop
  788.  
  789.         tst.b    17(a3,d7.w)        ;EG off
  790.         beq.w    bpskip10        ;Yes ??
  791.         tst.b    19(a3,d7.w)        ;Is there an init value for EG
  792.         beq.w    bpskip10        ;No ??
  793.         moveq    #0,d3
  794.         move.b    19(a3,d7.w),d3
  795.         lsr.l    #3,d3             ;Divide by 8 ->0..31
  796.         move.b    d3,$1c(a2)        ;Current EG Value
  797.         subq.l    #1,d3             ;-1,DBRA correction
  798. eg3loop        neg.b    (a4)+
  799.         dbra    d3,eg3loop
  800.         bra.w    bpskip10
  801.  
  802. bpplayarp    lea    bpper(pc),a4
  803.         ext.w    d4
  804.         asl.w    #1,d4
  805.         move.w    -2(a4,d4.w),6(a1)
  806.         rts
  807.  
  808. bpsynth        move.l    a5,-(sp)
  809.         moveq    #3,d0
  810.         lea    SMON_BPCurrent(a5),a2
  811.         lea    $dff0a0,a1
  812.         move.l    SMON_Module(a5),a3
  813.         lea    SMON_BPBuffer(a5),a5
  814. bpsynthloop    tst.b    $1a(a2)            ;Is synthetic sound
  815.         beq.b    bpnosynth        ;No ??
  816.         bsr.b    bpyessynth        ;Yes         
  817. bpnosynth    lea    $24(a5),a5
  818.         lea    $20(a2),a2
  819.         lea    $10(a1),a1
  820.         dbra    d0,bpsynthloop
  821.         move.l    (sp)+,a5
  822.         rts
  823.  
  824. bpyessynth    moveq    #0,d7
  825.         move.b    3(a2),d7        ;Which instr. was I playing
  826.         lsl.w    #5,d7             ;x32, is length of instr.
  827.         tst.b    $1f(a2)         ;ADSR off
  828.         beq.b    bpendadsr        ;Yes ??
  829.         subq.w    #1,$18(a2)        ;Delay,May I
  830.         bne.b    bpendadsr        ;No ??
  831.         moveq    #0,d3
  832.         move.b    8(a3,d7.w),d3
  833.         move.w    d3,$18(a2)        ;Reset Delay Counter
  834.         move.l    4(sp),a4
  835.         move.l    SMON_Tables(a4),a4
  836.         move.b    5(a3,d7.w),d3        ;Which ADSR table
  837.         lsl.l    #6,d3             ;x64
  838.         add.l    d3,a4             ;This is my table
  839.         move.w    $12(a2),d3        ;Get ADSR table pointer
  840.         moveq    #0,d4
  841.         move.b    (a4,d3.w),d4        ;Value from table
  842.         add.b    #128,d4         ;Want it from 0..255
  843.         lsr.w    #2,d4             ;And now from 0..63
  844.         moveq    #0,d3
  845.         move.b    2(a2),d3        ;Current Volume
  846.         mulu    d3,d4             ;MultiPly with table volume
  847.         lsr.w    #6,d4             ;Divide by 64=New volume
  848.  
  849.         movem.l    d0/a5,-(sp)
  850.         move.l    12(sp),a5
  851.         move.w    d4,d0
  852.         bsr.w    calvol
  853.         move.w    d0,8(a1)        ;Volume in hardware
  854.         movem.l    (sp)+,d0/a5
  855.  
  856.         addq.w    #1,$12(a2)        ;Increment of ADSR pointer
  857.         move.w    6(a3,d7.w),d4        ;Length of adsr table
  858.         cmp.w    $12(a2),d4        ;End of table reached
  859.         bne.b    bpendadsr        ;No ??
  860.         clr.w    $12(a2)         ;Clear ADSR Pointer
  861.         cmpi.b    #1,$1f(a2)        ;Once
  862.         bne.b    bpendadsr        ;No ??
  863.         clr.b    $1f(a2)            ;ADSR off
  864. bpendadsr    tst.b    $1e(a2)            ;LFO On
  865.         beq.b    bpendlfo        ;No ??
  866.         subq.w    #1,$16(a2)        ;LFO delay,May I
  867.         bne.b    bpendlfo        ;No
  868.         moveq    #0,d3
  869.         move.b    16(a3,d7.w),d3
  870.         move.w    d3,$16(a2)        ;Set LFO Count
  871.         move.l    4(sp),a4
  872.         move.l    SMON_Tables(a4),a4
  873.         move.b    10(a3,d7.w),d3        ;Which LFO table
  874.         lsl.l    #6,d3             ;x64
  875.         add.l    d3,a4
  876.         move.w    $10(a2),d3        ;LFO pointer
  877.         moveq    #0,d4
  878.         move.b    (a4,d3.w),d4        ;That's my value
  879.         ext.w    d4             ;Make it a word
  880.         ext.l    d4             ;And a longword
  881.         moveq    #0,d5
  882.         move.b    11(a3,d7.w),d5        ;LFO depth
  883.         tst.b    d5
  884.         beq.b    bpnotx
  885.         divs    d5,d4             ;Calculate it
  886. bpnotx        move.w    (a2),d5         ;Period
  887.         add.w    d4,d5             ;New Period
  888.         move.w    d5,6(a1)        ;In hardware
  889.         addq.w    #1,$10(a2)        ;Next position
  890.         move.w    12(a3,d7.w),d3        ;LFO table Length
  891.         cmp.w    $10(a2),d3        ;End Reached
  892.         bne.b    bpendlfo        ;NO ??
  893.         clr.w    $10(a2)             ;Reset LFO Pointer
  894.         cmpi.b    #1,$1e(a2)        ;Once LFO
  895.         bne.b    bpendlfo        ;NO ??
  896.         clr.b    $1e(a2)         ;LFO Off
  897. bpendlfo    tst.b    $1d(a2)         ;EG On
  898.         beq.w    bpendeg            ;No ??
  899.         subq.w    #1,$14(a2)        ;EG delay,May I
  900.         bne.w    bpendeg         ;No
  901.         tst.l    (a5)
  902.         beq.b    bpendeg
  903.         moveq    #0,d3
  904.         move.b    24(a3,d7.w),d3
  905.         move.w    d3,$14(a2)        ;Set EG Count
  906.         move.l    4(sp),a4
  907.         move.l    SMON_Tables(a4),a4
  908.         move.b    18(a3,d7.w),d3        ;Which EG table
  909.         lsl.l    #6,d3             ;x64
  910.         add.l    d3,a4
  911.         move.w    $e(a2),d3        ;EG pointer
  912.         moveq    #0,d4
  913.         move.b    (a4,d3.w),d4        ;That's my value
  914.         move.l    (a5),a4         ;Pointer to waveform
  915.         add.b    #128,d4         ;0..255
  916.         lsr.l    #3,d4             ;0..31
  917.         moveq    #0,d3
  918.         move.b    $1c(a2),d3        ;Old EG Value
  919.         move.b    d4,$1c(a2)
  920.         add.l    d3,a4             ;WaveForm Position
  921.         move.l    a5,a6             ;Buffer
  922.         add.l    d3,a6             ;Position
  923.         addq.l    #4,a6             ;For adress in buffer
  924.         cmp.b    d3,d4             ;Compare old with new value
  925.         beq.b    bpnexteg        ;no change ??
  926.         bgt.b    bpishigh        ;new value is higher
  927. bpislow        sub.l    d4,d3             ;oldvalue-newvalue
  928.         subq.l    #1,d3             ;Correction for DBRA
  929. bpegloop1a    move.b    -(a6),d4
  930.         move.b    d4,-(a4)
  931.         dbra    d3,bpegloop1a
  932.         bra.b    bpnexteg
  933.  
  934. bpishigh    sub.l    d3,d4             ;Newvalue-oldvalue
  935.         subq.l    #1,d4             ;Correction for DBRA
  936. bpegloop1b    move.b    (a6)+,d3
  937.         neg.b    d3
  938.         move.b    d3,(a4)+        ;DoIt
  939.         dbra    d4,bpegloop1b
  940.  
  941. bpnexteg    addq.w    #1,$e(a2)        ;Next position
  942.         move.w    20(a3,d7.w),d3        ;EG table Length
  943.         cmp.w    $e(a2),d3        ;End Reached
  944.         bne.b    bpendeg            ;NO ??
  945.         clr.w    $e(a2)             ;Reset EG Pointer
  946.         cmpi.b    #1,$1d(a2)        ;Once EG
  947.         bne.b    bpendeg         ;NO ??
  948.         clr.b    $1d(a2)         ;EG Off
  949. bpendeg        rts
  950. ;------------------------------------------------------------------------------
  951. ; Calculate New Volume
  952. ;
  953. ; IN :    D0 = Volume
  954. ;    A5 = SMON Structure
  955. ;
  956. ; OUT:    D0 = New Volume
  957. ;
  958.  
  959. CALVOL    move.l    a5,-(sp)
  960.     move.l    SMON_Global(a5),a5
  961.     move.l    APG_CalcVolume(a5),a5
  962.     jsr    (a5)
  963.     move.l    (sp)+,a5
  964.     rts
  965. ;------------------------------------------------------------------------------
  966.     dc.w 6848,6464,6080,5760,5440,5120,4832,4576,4320,4064,3840,3616
  967.     dc.w 3424,3232,3040,2880,2720,2560,2416,2288,2160,2032,1920,1808
  968.     dc.w 1712,1616,1520,1440,1360,1280,1208,1144,1080,1016,0960,0904
  969. bpper    dc.w 0856,0808,0760,0720,0680,0640,0604,0572,0540,0508,0480,0452
  970.     dc.w 0428,0404,0380,0360,0340,0320,0302,0286,0270,0254,0240,0226
  971.     dc.w 0214,0202,0190,0180,0170,0160,0151,0143,0135,0127,0120,0113
  972.     dc.w 0107,0101,0095,0090,0085,0080,0076,0072,0068,0064,0060,0057
  973. ;------------------------------------------------------------------------------
  974. ; ModuleName
  975. ;
  976. ; IN :    A1 = Address
  977. ;
  978. ; OUT:    A0 = Pointer To The Name
  979. ;
  980.  
  981. SM_ModuleName
  982.     move.l    a1,a0
  983.     rts
  984. ;------------------------------------------------------------------------------
  985. ; GetMaxPattern
  986. ;
  987. ; IN :    A1 = Address
  988. ;
  989. ; OUT:    D1 = Number Of Patterns
  990. ;
  991.  
  992. SM_GetMaxPattern
  993.     movem.l    d0/d2/a1,-(sp)
  994.  
  995.     move.w    30(a1),d0        ;d1 now contains length in steps
  996.     move.l    #512,d2
  997.     moveq    #1,d1            ;1 is highest pattern number
  998.     mulu    #4,d0             ;4 voices per step
  999.     subq.w    #1,d0             ;correction for DBRA
  1000. .GTMAX1    cmp.w    (a1,d2.l),d1        ;Is it higher
  1001.     bge.b    .gtmax2            ;No
  1002.     move.w    (a1,d2.l),d1        ;Yes, so let D2 be highest
  1003. .GTMAX2    addq.l    #4,d2             ;Next Voice
  1004.     dbra    d0,.gtmax1        ;And search
  1005.  
  1006.     movem.l    (sp)+,d0/d2/a1
  1007.     rts
  1008. ;------------------------------------------------------------------------------
  1009. ; GetMaxSample
  1010. ;
  1011. ; IN :    A1 = Address
  1012. ;
  1013. ; OUT:    D1 = Number Of Samples
  1014. ;
  1015.  
  1016. SM_GetMaxSample
  1017.     moveq    #15,d1
  1018.     rts
  1019. ;------------------------------------------------------------------------------
  1020. ; GetSongLength
  1021. ;
  1022. ; IN :    A1 = Address
  1023. ;
  1024. ; OUT:    D1 = Length
  1025. ;
  1026.  
  1027. SM_GetSongLength
  1028.     move.w    30(a1),d1
  1029.     rts
  1030. ;------------------------------------------------------------------------------
  1031. ; GetSongPos
  1032. ;
  1033. ; IN :    A1 = Address
  1034. ;
  1035. ; OUT:    D1 = Position (0-x)
  1036. ;
  1037.  
  1038. SM_GetSongPos
  1039.     move.l    a0,-(sp)
  1040.     lea    SM_DataArea,a0
  1041.     move.w    SMON_BPStep(a0),d1
  1042.     move.l    (sp)+,a0
  1043.     rts
  1044. ;------------------------------------------------------------------------------
  1045. ; Rewind
  1046. ;
  1047. ; IN :    A1 = Address
  1048. ;
  1049. ; OUT:    D1 = New Position
  1050. ;
  1051.  
  1052. SM_Rewind
  1053.     movem.l    a0-a1,-(sp)
  1054.     lea    SM_DataArea,a0
  1055.  
  1056.     move.w    SMON_BPStep(a0),d1
  1057.     beq.b    sforwa1
  1058.     subq.w    #1,d1
  1059.     bra.b    sforwa1
  1060. ;------------------------------------------------------------------------------
  1061. ; Forward
  1062. ;
  1063. ; IN :    A1 = Address
  1064. ;
  1065. ; OUT:    D1 = New Position
  1066. ;
  1067.  
  1068. SM_Forward
  1069.     movem.l    a0-a1,-(sp)
  1070.     lea    SM_DataArea,a0
  1071.  
  1072.     move.w    SMON_BPStep(a0),d1
  1073.     addq.w    #1,d1
  1074.     cmp.w    30(a1),d1
  1075.     blt.b    sforwa1
  1076.     moveq    #0,d1
  1077.  
  1078. SFORWA1    move.w    d1,SMON_BPStep(a0)
  1079.     clr.b    SMON_BPPatCount(a0)
  1080.  
  1081.     movem.l    (sp)+,a0-a1
  1082.     rts
  1083. ;------------------------------------------------------------------------------
  1084.     SECTION    NullSample,DATA_C
  1085.  
  1086. NULL    dc.l    0
  1087. ;------------------------------------------------------------------------------
  1088.     SECTION    SM_DataArea,BSS
  1089.  
  1090. SM_DataArea
  1091.     ds.b    SoundMonStruct_SIZEOF
  1092. ;------------------------------------------------------------------------------
  1093. SLUT
  1094.